pub(crate) mod with_vec_no_bg_task;

use std::{
    future::Future,
    sync::{Arc, Mutex},
    time::Duration,
};
use tokio::task::AbortHandle;

pub(crate) struct AutoAbort(Arc<Mutex<Vec<AbortHandle>>>);

#[allow(dead_code)]
impl AutoAbort {
    pub(crate) fn new() -> Self {
        let lst = Arc::new(Mutex::new(Vec::<AbortHandle>::new()));
        std::thread::spawn({
            let lst = Arc::clone(&lst);
            move || loop {
                std::thread::sleep(Duration::from_secs(10));
                {
                    let mut lst = lst.lock().unwrap();

                    let orig_len = lst.len();
                    let mut len = orig_len;
                    for i in 0..orig_len {
                        if lst[i].is_finished() {
                            lst.swap(i, orig_len - 1);
                            len -= 1;
                        }
                    }
                    lst.truncate(len);
                }
            }
        });
        AutoAbort(lst)
    }

    pub(crate) fn spawn<F>(&self, f: F)
    where
        F: Future + Send + 'static,
        F::Output: Send + 'static,
    {
        self.0.lock().unwrap().push(tokio::spawn(f).abort_handle());
    }
}

impl Drop for AutoAbort {
    fn drop(&mut self) {
        self.0.lock().unwrap().iter().for_each(AbortHandle::abort);
    }
}
